package model.semantics;

import java.util.List;

import model.State;
import model.parser.ParserException;

/**
 * Element node. Retrieves an element from a list. Note that due to the
 * limitation that the return type must be an integer, we evaluate the given
 * element and return the result. This could be changed by making everything
 * return Node<T> instead of T, but it seems unlikely to happen at this point.
 * 
 * @author Sterling Dorminey.
 * 
 */
public class ElementNode extends Node<Integer> {

    public Node<Integer> myIndexNode;
    public VariableNode<Integer> myVariableNode;

    public ElementNode(Node<Integer> indexNode, Node<Integer> variableNode) {
        if (!(variableNode instanceof VariableNode)) {
            throw ParserException.BAD_ARGUMENTS;
        }

        myIndexNode = indexNode;
        myVariableNode = (VariableNode<Integer>) variableNode;
    }

    @Override
    public Integer evaluate(State<Integer> state) {
        int index = myIndexNode.evaluate(state);

        Node<Integer> _listNode = state
                .getAssignment(myVariableNode.getLabel());
        if (!(_listNode instanceof AggregatorNode)) {
            throw ParserException.BAD_ARGUMENTS;
        }

        AggregatorNode<Integer> listNode = (AggregatorNode<Integer>) _listNode;

        List<Node<Integer>> list = listNode.getList();
        if (index < 0 || index > listNode.getList().size())
            return 0;

        int element = list.get(index).evaluate(state);

        return element;
    }

}
